#compdef msfvenom
# ------------------------------------------------------------------------------
# License
# -------
# This file is part of the Metasploit Framework and is released under the MSF
# License, please see the COPYING file for more details.
#
# ------------------------------------------------------------------------------
# Description
# -----------
#
#  Completion script for the Metasploit Framework's msfvenom command
#  (http://www.metasploit.com/).
#
# ------------------------------------------------------------------------------
# Authors
# -------
#
#  * Spencer McIntyre
#
# ------------------------------------------------------------------------------

_msfvenom_archs_list=(
  'aarch64'
  'armbe'
  'armle'
  'cbea'
  'cbea64'
  'cmd'
  'dalvik'
  'firefox'
  'java'
  'mips'
  'mips64'
  'mips64le'
  'mipsbe'
  'mipsle'
  'nodejs'
  'php'
  'ppc'
  'ppc64'
  'ppc64le'
  'ppce500v2'
  'python'
  'r'
  'ruby'
  'sparc'
  'sparc64'
  'tty'
  'x64'
  'x86'
  'x86_64'
  'zarch'
)

_msfvenom_arch() {
  _describe -t archs 'available archs' _msfvenom_archs_list || compadd "$@"
}

_msfvenom_encoders_list=(
  'cmd/brace'
  'cmd/echo'
  'cmd/generic_sh'
  'cmd/ifs'
  'cmd/perl'
  'cmd/powershell_base64'
  'cmd/printf_php_mq'
  'generic/eicar'
  'generic/none'
  'mipsbe/byte_xori'
  'mipsbe/longxor'
  'mipsle/byte_xori'
  'mipsle/longxor'
  'php/base64'
  'ppc/longxor'
  'ppc/longxor_tag'
  'ruby/base64'
  'sparc/longxor_tag'
  'x64/xor'
  'x64/xor_context'
  'x64/xor_dynamic'
  'x64/zutto_dekiru'
  'x86/add_sub'
  'x86/alpha_mixed'
  'x86/alpha_upper'
  'x86/avoid_underscore_tolower'
  'x86/avoid_utf8_tolower'
  'x86/bloxor'
  'x86/bmp_polyglot'
  'x86/call4_dword_xor'
  'x86/context_cpuid'
  'x86/context_stat'
  'x86/context_time'
  'x86/countdown'
  'x86/fnstenv_mov'
  'x86/jmp_call_additive'
  'x86/nonalpha'
  'x86/nonupper'
  'x86/opt_sub'
  'x86/service'
  'x86/shikata_ga_nai'
  'x86/single_static_bit'
  'x86/unicode_mixed'
  'x86/unicode_upper'
  'x86/xor_dynamic'
)

_msfvenom_encoder() {
  _describe -t encoders 'available encoders' _msfvenom_encoders_list || compadd "$@"
}

_msfvenom_formats_list=(
  # Executable formats
  'asp'
  'aspx'
  'aspx-exe'
  'axis2'
  'dll'
  'ducky-script-psh'
  'elf'
  'elf-so'
  'exe'
  'exe-only'
  'exe-service'
  'exe-small'
  'hta-psh'
  'jar'
  'jsp'
  'loop-vbs'
  'macho'
  'msi'
  'msi-nouac'
  'osx-app'
  'psh'
  'psh-cmd'
  'psh-net'
  'psh-reflection'
  'vba'
  'vba-exe'
  'vba-psh'
  'vbs'
  'war'
  # Transform formats
  'bash'
  'c'
  'csharp'
  'dw'
  'dword'
  'hex'
  'java'
  'js_be'
  'js_le'
  'num'
  'perl'
  'pl'
  'powershell'
  'ps1'
  'py'
  'python'
  'raw'
  'rb'
  'ruby'
  'sh'
  'vbapplication'
  'vbscript'
)

_msfvenom_formats() {
  _describe -t formats 'available formats' _msfvenom_formats_list || compadd "$@"
}

_msfvenom_platforms_list=(
  'aix'
  'android'
  'apple_ios'
  'brocade'
  'bsd'
  'bsdi'
  'cisco'
  'firefox'
  'freebsd'
  'hardware'
  'hpux'
  'irix'
  'java'
  'javascript'
  'juniper'
  'linux'
  'mainframe'
  'multi'
  'netbsd'
  'netware'
  'nodejs'
  'openbsd'
  'osx'
  'php'
  'python'
  'r'
  'ruby'
  'solaris'
  'unifi'
  'unix'
  'unknown'
  'windows'
)

_msfvenom_platform() {
  _describe -t platforms 'available platforms' _msfvenom_platforms_list || compadd "$@"
}

_msfvenom_payload() {
  local cacheFile="$HOME/.msf4/store/modules_metadata.json"
  local -a _msfvenom_payloads_list
  [ -f "$cacheFile" ] || cacheFile="/opt/metasploit/db/modules_metadata_base.json"
  if [ ! -f "$cacheFile" ]; then
    _message -r "Cannot find metasploit cache file. Run msfconsole to populate it"
    compadd "$@"
  else
    _msfvenom_payloads_list=("${(f)$(sed -n '/"type": "payload"/,/"ref_name"/p' "$cacheFile" | grep -E '(ref_name|description)' | cut -d '"' -f 4 | sed -n 'h;n;p;g;p' | sed 'N;s/\n/:/; s/\\n.*$//')}")
    _describe -t payloads 'available payloads' _msfvenom_payloads_list || compadd "$@"
  fi
}

_arguments \
  "--smallest[Generate the smallest possible payload using all available encoders]" \
  "--sec-name[The new section name to use when generating large Windows binaries. Default: random 4-character alpha string]" \
  "--service-name[The service name to use when generating a service binary]:value" \
  "--encoder-space[The maximum size of the encoded payload (defaults to the -s value)]:length" \
  "--encrypt[The type of encryption or encoding to apply to the shellcode]:value" \
  "--encrypt-key[A key to be used for --encrypt]:value" \
  "--encrypt-iv[An initialization vector for --encrypt]:value" \
  "--list-options[List --payload <value>'s standard, advanced and evasion options]" \
  "--pad-nops[Use nopsled size specified by -n \<length\> as the total payload size, auto-prepending a nopsled of quantity (nops minus payload length)]" \
  "--platform[The platform for --payload (use --list platforms to list)]:target platform:_msfvenom_platform" \
  {-a,--arch}"[The architecture to use for --payload and --encoders (use --list archs to list)]:architecture:_msfvenom_arch" \
  {-b,--bad-chars}"[Characters to avoid example: '\x00\xff']:bad characters" \
  {-c,--add-code}"[Specify an additional win32 shellcode file to include]:shellcode file:_files" \
  {-e,--encoder}"[The encoder to use (use --list encoders to list)]:encoder:_msfvenom_encoder" \
  {-f,--format}"[Output format (use --list formats to list)]:output format:_msfvenom_formats" \
  {-h,--help}"[Show the help banner]" \
  {-i,--iterations}"[The number of times to encode the payload]:iterations" \
  {-k,--keep}"[Preserve the --template behavior and inject the payload as a new thread]" \
  {-l,--list}"[List all modules for \[type\]]:module type:(payloads encoders nops platforms archs encrypt formats all)" \
  {-n,--nopsled}"[Prepend a nopsled of \[length\] size on to the payload]:nopsled length" \
  {-o,--out}"[Save the payload to a file]:output file:_files" \
  {-p,--payload}"[Payload to use (--list payloads to list, --list-options for arguments). Specify '-' or STDIN for custom]:target payload:_msfvenom_payload" \
  {-s,--space}"[The maximum size of the resulting payload]:length" \
  {-t,--timeout}"[The number of seconds to wait when reading the payload from STDIN (default 30, 0 to disable)]:second" \
  {-v,--var-name}"[Specify a custom variable name to use for certain output formats]:value" \
  {-x,--template}"[Specify a custom executable file to use as a template]:template file:_files"
